home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / audio / music / sonixpek.1
Internet Message Format  |  1989-05-18  |  35KB

  1. Path: xanth!ames!amdahl!oliveb!sun!swap!page
  2. From: page%swap@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i141:  sonixpeek - list instruments in sonix scores
  5. Message-ID: <105552@sun.Eng.Sun.COM>
  6. Date: 17 May 89 15:36:00 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 1008
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: ecarroll@vax1.tcd.ie (Eddy Carroll)
  12. Posting-number: Volume 89, Issue 141
  13. Archive-name: audio/music/sonixpeek.1
  14.  
  15. SonixPeek is a utility to let you list all the instruments used by one
  16. or more Aegis Sonix score files. It can scan individual files, or
  17. search one or more directories checking all score files in each
  18. directory. The output is a list of all the instruments you need to
  19. have present in order to be able to play the indicated score files.
  20.  
  21. [uuencoded executable included.  ..bob]
  22.  
  23. # This is a shell archive.
  24. # Remove anything above and including the cut line.
  25. # Then run the rest of the file through 'sh'.
  26. # Unpacked files will be owned by you and have default permissions.
  27. #----cut here-----cut here-----cut here-----cut here----#
  28. #!/bin/sh
  29. # shar: SHell ARchive
  30. # Run the following text through 'sh' to create:
  31. #    makefile
  32. #    sonixpeek.c
  33. #    sonixpeek.n
  34. #    sonixpeek.uu
  35. #    tiny.a
  36. # This is archive 1 of a 1-part kit.
  37. # This archive created: Wed May 17 20:31:29 1989
  38. echo "extracting makefile"
  39. sed 's/^X//' << \SHAR_EOF > makefile
  40. X#
  41. X# Aztec Make makefile, for Lattice C V4.0 :-)
  42. X#
  43. X# Sonixpeek by Eddy Carroll, April 1989
  44. X#
  45. X
  46. XZOOEXE = sonixpeek sonixpeek.doc
  47. XZOOSRC = tiny.o tiny.a sonixpeek.c sonixpeek.1 makefile
  48. XOBJS   = tiny.o sonixpeek.o
  49. X#
  50. X#
  51. X#
  52. X.c.o:
  53. X    lc -s -v $*.c
  54. X.a.o:
  55. X    sys:lattice/c/asm -isys:include/ -u $*.a
  56. X.n.doc:
  57. X    nro >$*.doc -ms:an $*.n
  58. X#
  59. X#
  60. X#
  61. Xall: sonixpeek sonixpeek.doc
  62. X
  63. Xsonixpeek: $(OBJS)
  64. X    blink from $(OBJS) to sonixpeek sc sd nd map ram:map
  65. X
  66. Xsonixpeek.o: sonixpeek.c
  67. Xsonixpeek.doc: sonixpeek.n
  68. X
  69. Xzoo:    sonixpeek.zoo
  70. Xzoosrc: sonixpeeksrc.zoo
  71. X
  72. Xsonixpeek.zoo: $(ZOOEXE)
  73. X    -delete sonixpeek.zoo
  74. X    zoo a sonixpeek.zoo $(ZOOEXE)
  75. X
  76. Xsonixpeeksrc.zoo: $(ZOOSRC)
  77. X    -delete sonixpeeksrc.zoo
  78. X    zoo a sonixpeeksrc.zoo $(ZOOSRC)
  79. X
  80. Xclean:
  81. X    -delete "#?.bak"
  82. SHAR_EOF
  83. echo "extracting sonixpeek.c"
  84. sed 's/^X//' << \SHAR_EOF > sonixpeek.c
  85. X/*
  86. X * SONIXPEEK.C                              by Eddy Carroll, April 1988
  87. X * ~~~~~~~~~~~                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  88. X *
  89. X * Scans one or more Aegis Sonix music files building a list of unique
  90. X * instruments used within those files. At the end, a list of the
  91. X * instruments found is printed (can be redirected to a file if
  92. X * desired).
  93. X *
  94. X * Usage: SonixPeek {-h} {-i} {-n} {-ofile} {-xdirectory} filename ...
  95. X *
  96. X * If filename is a Sonix file, then only that file is scanned. If
  97. X * filename is a directory, then all the files in that directory which
  98. X * contain Sonix files are scanned.
  99. X * 
  100. X * The -h flag suppresses the printing of the header which is normally
  101. X * present at the top of the list of instruments.
  102. X *
  103. X * If the -i (interactive) flag is present, then after each file is
  104. X * found, the user is asked whether it should be included or not when
  105. X * building the list of instruments.
  106. X *
  107. X * If the -o flag is present, then the list of instruments is stored
  108. X * in the specified file, rather than being displayed on the screen.
  109. X *
  110. X * If the -x flag is present, then the output is given in the form
  111. X * of an executable file which consists of a line for each instrument
  112. X * found of the form COPY <instrument> TO <directory>, where <directory>
  113. X * is given immediately after the -x switch.
  114. X *
  115. X * If the -n flag is present, then the list of instruments found in each
  116. X * file, when a directory is being searched, is not printed.
  117. X *
  118. X * DISTRIBUTION
  119. X * I retain copyright to the source and executable code for SonixPeek, but
  120. X * it may be freely redistributed as long as no profit is made from it.
  121. X * 
  122. X * Compiles under Lattice C V4.0
  123. X *
  124. X * Note: Some of this code is messy. Have patience with it :-)
  125. X *
  126. X */
  127. X
  128. X#include <exec/types.h>
  129. X#include <libraries/dos.h>
  130. X#include <proto/exec.h>
  131. X#include <proto/dos.h>
  132. X#include <proto/intuition.h>
  133. X#include <string.h>
  134. X
  135. X/* The following is a quick hack to avoid having to link with lc.lib */
  136. X#define strcat(p,q) (strcpy((p)+strlen(p),(q)))
  137. X
  138. X/*
  139. X * New handler for Ctrl-C. Checks if CTRL-C received, and if it has, sets
  140. X * the global CtrlC variable to true.
  141. X */
  142. Xint CtrlC;
  143. X#define chkabort() (CtrlC |= ((SetSignal(0,0) & SIGBREAKF_CTRL_C)))
  144. X
  145. X#define tolower(c) ((c) >= 'A' && (c) <= 'Z' ? (c) + 'a' - 'A' : (c))
  146. X
  147. X#define EOL      '\012'
  148. X#define EOF      '\037'
  149. X#define TAB      '\011'
  150. X#define CR       '\015'
  151. X
  152. X#define MAXINS        1000    /* Only 200 instruments allowed        */
  153. X#define MAXFILENUM    200        /* No more than 200 scores allowed    */
  154. X#define MAXSTRING    256        /* Maximum length of a string        */
  155. X
  156. X#define INDENT ("    ")        /* Amount to indent instruments by    */
  157. X
  158. X/* IFF ID definitions */
  159. X
  160. X#define MakeID(a,b,c,d) (long)((long)(a)<<24 | (long)(b)<<16 | (c)<<8 | (d))
  161. X#define FORM MakeID('F','O','R','M')
  162. X#define SMUS MakeID('S','M','U','S')
  163. X#define NAME MakeID('N','A','M','E')
  164. X#define SNX1 MakeID('S','N','X','1')
  165. X#define INS1 MakeID('I','N','S','1')
  166. X#define TRAK MakeID('T','R','A','K')
  167. X
  168. X#define roundup(a) ((a + 1L) & ~1L)
  169. X
  170. Xint interactive;        /* TRUE if interactive selection of files            */
  171. Xint multi;                /* TRUE if a directory specified instead of file     */
  172. Xint supress;            /* TRUE if listing of instruments is supressed        */
  173. Xint noheader;            /* TRUE if no header ouput at start of instr. list    */
  174. Xchar *dirname;            /* Directory to copy to for -x option                */
  175. Xchar *suffix[] =
  176. X    {".ss", ".instr"};    /* For creating 'copy' batch file                    */
  177. X
  178. XLONG Examine(), ExNext(), Read(), Write();
  179. XBPTR Lock(), CurrentDir();
  180. X
  181. Xint numins;                    /* Current number of instruments    */
  182. Xint numfiles;                /* Current number of files             */
  183. Xchar *ins[MAXINS];            /* Room for 1000 instruments        */
  184. Xchar *files[MAXFILENUM];    /* Room for 200 files                */
  185. X
  186. XBPTR stdin, stdout, stderr, infile, outfile;
  187. Xstruct FileInfoBlock myfib;
  188. X
  189. X/*
  190. X *        The following lets us use our own version of malloc(). The only
  191. X *        additional requirements are that we open intuition.library first,
  192. X *        and call FreeRemember(&memkey,TRUE) just before exiting.
  193. X */
  194. Xstruct Remember *memkey;    /* Used for tracking memory */
  195. X#define malloc(n) (AllocRemember(&memkey,n,0L))
  196. Xstruct IntuitionBase *IntuitionBase;
  197. X
  198. X/*
  199. X *        Output string to file. Note that if CTRL-C has been typed,
  200. X *        output is suppressed.
  201. X */
  202. X
  203. Xvoid fprint(f, s)
  204. XBPTR f;
  205. Xchar *s;
  206. X{
  207. X    if (!CtrlC) {
  208. X        Write(f, s, strlen(s));
  209. X        chkabort();
  210. X    }
  211. X}
  212. X
  213. X/*
  214. X *        Outputs 3 strings to file f (handy for printing "String" var "String")
  215. X *        The strings are concatenated first to ensure that they are printed
  216. X *        as a single unit, and won't be interrupted by ^C, or even just the
  217. X *        user pressing space, if the output is stdout or stderr.
  218. X */
  219. Xvoid fprint3(f,s1,s2,s3)
  220. XBPTR f;
  221. Xchar *s1,*s2,*s3;
  222. X{
  223. X    static char buf[MAXSTRING * 3];
  224. X    strcpy(buf,s1);
  225. X    strcat(buf,s2);
  226. X    strcat(buf,s3);
  227. X    fprint(f,buf);
  228. X}
  229. X
  230. X/*
  231. X *        print() and print3() are similar to fprint() and fprint3(), but
  232. X *        they output directly to stderr.
  233. X */
  234. X#define print(s) fprint(stderr,s)
  235. X#define print3(s1,s2,s3) fprint3(stderr,s1,s2,s3)
  236. X
  237. X/*
  238. X *        Standard exit routine for program. Deallocates resources and exits.
  239. X *        If it spots CtrlC has been pressed, it prints an appropriate message.
  240. X */
  241. X
  242. Xvoid abort(code)
  243. Xint code;    /* Exit code */
  244. X{
  245. X    if (CtrlC)
  246. X        Write(stderr,"^C\n",3);    /* print() won't work when CtrlC is true */
  247. X    if (outfile != stdout && outfile != NULL)
  248. X        Close(outfile);
  249. X    if (stderr)
  250. X        Close(stderr);
  251. X    if (memkey)
  252. X        FreeRemember(&memkey,TRUE);
  253. X    if (IntuitionBase) 
  254. X        CloseLibrary(IntuitionBase);
  255. X    exit(code);
  256. X}
  257. X
  258. X/*
  259. X *        Prints help message to standard output
  260. X */
  261. Xvoid help()
  262. X{
  263. Xfprint3(stderr,"\n\
  264. XSonixPeek Instrument Lister Copyright Eddy Carroll April 1988\n\
  265. X\n\
  266. XUsage: SonixPeek {-h} {-i} {-n} {-ofile} {-xdirectory} file ...\n\
  267. X\n\
  268. XFile is the Aegis Sonix file for which the instruments are to\n","\
  269. Xbe listed. If it is a directory, then all the Sonix files in\n\
  270. Xthat directory are checked, and a sorted list of the instruments\n\
  271. Xcontained in all of them is prepared. The flags operate as follows:\n\
  272. X\n","\
  273. X -h  Suppress output of header at start of instrument listing\n\
  274. X\n\
  275. X -i  Ask user whether or not to include each score found\n\
  276. X\n\
  277. X -n  Don't list instruments as they are found\n\
  278. X\n");fprint(stderr,"\
  279. X -o  Redirect sorted output to named file\n\
  280. X\n\
  281. X -x  Format output as an execute file which will copy all the\n\
  282. X     instruments found to the named directory\n\
  283. X\n");
  284. X}
  285. X
  286. X/*** Start of actual program ***/
  287. X
  288. Xvoid main(argc, argv)
  289. Xint argc;
  290. Xchar *argv[];
  291. X{
  292. X
  293. X    void addinstrument(), skip(), dumpins();
  294. X    char charin();
  295. X    BPTR mylock, oldlock;
  296. X    char *fname;
  297. X
  298. X    stdin   = Input();
  299. X    stderr  = Open("*",MODE_NEWFILE);
  300. X    outfile = stdout = Output();
  301. X    infile  = 0;
  302. X
  303. X    if ((IntuitionBase = OpenLibrary("intuition.library",0L)) == NULL)
  304. X        abort(99);
  305. X
  306. X    /* Scan command line for possible switches */
  307. X
  308. X    for ( argv++; argc > 1 && argv[0][0] == '-'; argc--,argv++) {
  309. X        switch (tolower(argv[0][1])) {
  310. X
  311. X        case 'h':    noheader = 1;
  312. X                    break;
  313. X
  314. X        case 'i':    interactive = 1;
  315. X                    break;
  316. X
  317. X        case 'n':   supress = 1;
  318. X                    break;
  319. X
  320. X        case 'o':    if ((outfile = Open(argv[0]+2,MODE_NEWFILE)) == 0) {
  321. X                        print3("Can't open file ",argv[0]+2," for output.\n");
  322. X                        abort(20);
  323. X                    }
  324. X                    break;
  325. X
  326. X        case 'x':    dirname = argv[0] + 2;
  327. X                    break;
  328. X
  329. X        default:    print3("Unknown option ", argv[0], " ignored.\n");
  330. X                    break;
  331. X        }
  332. X    }
  333. X
  334. X    /* If missing filename, or filename == '?', print instructions */
  335. X
  336. X    if (argc == 1 || argv[0][0] == '?') {
  337. X        help();
  338. X        abort(0);
  339. X    }
  340. X    if (argc > 2)    /* More than one file specified */
  341. X        multi = 1;    /* so enable printing of instrument list for each file    */
  342. X
  343. X    /*
  344. X     *        Now scan each of the files or directories specified, reading
  345. X     *        the instruments from each one, and adding them to the list.
  346. X     */
  347. X    for ( ; argc > 1; argc--, argv++) {
  348. X        fname = argv[0];
  349. X        if ((mylock = Lock(fname, ACCESS_READ)) == 0L) {
  350. X            print3("Can't open file ",fname," for input.\n");
  351. X            abort(20);
  352. X        }
  353. X        Examine(mylock,&myfib);
  354. X        if (myfib.fib_DirEntryType > 0L) {
  355. X            multi = 1;
  356. X            oldlock = CurrentDir(mylock);
  357. X            while (chkabort(), ExNext(mylock, &myfib) && !CtrlC)
  358. X                if (myfib.fib_DirEntryType < 0L)
  359. X                    scan(&(myfib.fib_FileName), fname); 
  360. X            oldlock = CurrentDir(oldlock);
  361. X        } else
  362. X            scan(fname,NULL);
  363. X    }
  364. X    dumpins();
  365. X    UnLock(mylock);
  366. X    abort(0);
  367. X}
  368. X
  369. X/*
  370. X *        Scans filename for instruments. If found, they are added to the
  371. X *        list of instruments already in memory. Returns 0 for success, -1
  372. X *        if invalid file. The path parameter, which may be NULL, is the
  373. X *        path to be prefixed to the filename before it is stored in memory.
  374. X *        Note that this may entail adding a trailing '/' to the path.
  375. X */
  376. X
  377. Xint scan(filename,path)
  378. Xchar *filename;
  379. Xchar *path;
  380. X{
  381. X    LONG header[3];
  382. X    char instr[50], response[50], *p;
  383. X    int plen, foundinstr = 0;
  384. X
  385. X    if ((infile = Open(filename,MODE_OLDFILE)) == 0L) {
  386. X        print3("Can't open file ", filename, " for input\n");
  387. X        return(-1);
  388. X    }
  389. X
  390. X    if (Read(infile,(char *)header,8L) != 8L || header[0] != FORM) {
  391. X        Close(infile);
  392. X        return(-1);
  393. X    }
  394. X
  395. X    if (Read(infile,(char *)header,4L) != 4L || header[0] != SMUS) {
  396. X        Close(infile);
  397. X        return(-1);
  398. X    }
  399. X
  400. X    if (interactive) {
  401. X        print3("Include file ", filename, " (CR = no)? ");
  402. X        Read(stdin, response, 50L);
  403. X        if (tolower(*response) != 'y')
  404. X            return(-1);
  405. X    } else if (multi && !supress)
  406. X        fprint3(stdout, filename, ":\n", "");
  407. X
  408. X    while (chkabort(), Read(infile,(char *)header,8L) == 8L && !CtrlC) {
  409. X        if (header[0] != INS1) {
  410. X            skip(infile,header[1]);
  411. X        } else {
  412. X            skip(infile,4L); /* skip position of instrument parameter */
  413. X            Read(infile, instr, roundup(header[1]) - 4L);
  414. X            instr[header[1] - 4L] = '\0';    /* Null-terminate string */
  415. X            addinstrument(instr);
  416. X            foundinstr = 1;
  417. X        }
  418. X    }
  419. X    if (multi && !supress)
  420. X        fprint(stdout,"\n");
  421. X    if (foundinstr) {
  422. X        if (path) {
  423. X            plen = strlen(path);
  424. X            p = malloc(strlen(filename)+plen+2);
  425. X            /* Allocate extra byte for zero terminator and for possible '/' */
  426. X            strcpy(p, path);
  427. X            if (plen && p[plen-1] != ':' && p[plen-1] != '/')
  428. X                strcat(p,"/");
  429. X            strcat(p,filename);
  430. X        } else {
  431. X            p = malloc(strlen(filename)+1);
  432. X            strcpy(p,filename);
  433. X        }
  434. X        files[numfiles++] = p;
  435. X    }
  436. X    Close(infile);
  437. X    return(0);
  438. X}
  439. X
  440. Xvoid skip(file,size)
  441. XBPTR file;
  442. XLONG size;
  443. X{
  444. X    char s[256];
  445. X    LONG len = 1L;
  446. X    size = roundup(size);
  447. X    while (chkabort(), size > 0 && len && !CtrlC) {
  448. X        len = Read(file, s, (size > 256 ? 256 : size));
  449. X        size -= 256;
  450. X    }
  451. X}
  452. X
  453. X
  454. X/*
  455. X *        Adds instrument of length len into list of instruments, but only
  456. X *        if its not already present in the list.
  457. X */
  458. X
  459. Xvoid addinstrument(instr)
  460. Xchar *instr;
  461. X{
  462. X    int pos, i;
  463. X    if ((pos = matchins(instr)) != -1) {
  464. X        for (i = numins++; i > pos; i--)
  465. X            ins[i] = ins[i-1];
  466. X        ins[pos] = malloc(strlen(instr)+1);
  467. X        strcpy(ins[pos], instr);
  468. X    }
  469. X    if (multi && !supress) {
  470. X        fprint3(stdout, INDENT, instr, "\n");
  471. X    }
  472. X}
  473. X
  474. X/*
  475. X *        Compares string p to string s, ignoring case of alpha chars.
  476. X *        Returns -ve if p < s, 0 if p = s, +ve if p > s.
  477. X */
  478. X
  479. Xint mystrcmp(p,s)
  480. Xchar *p, *s;
  481. X{
  482. X    while (*p && *s && tolower(*p) == tolower(*s))
  483. X        p++, s++;
  484. X    return(tolower(*p) - tolower(*s));
  485. X}
  486. X
  487. X/*
  488. X *        Searches instrument array for a match with given instrument. 
  489. X *        Returns -1 if found, else position in array to insert new element.
  490. X */
  491. X
  492. Xint matchins(instr)
  493. Xchar *instr;
  494. X{
  495. X    int i, z;
  496. X
  497. X    for (i = 0; i < numins; i++) {
  498. X        if ((z = mystrcmp(instr, ins[i])) <= 0) {
  499. X            if (z)
  500. X                return(i); /* If less, insert here */
  501. X            else
  502. X                return(-1); /* If equal, don't insert  */
  503. X        }
  504. X    }
  505. X    return (i); /* Must be at end of list, so return last item */
  506. X}
  507. X
  508. X/*
  509. X *        Dumps instrument list to outfile
  510. X */
  511. Xvoid dumpins()
  512. X{
  513. X    int i, j;
  514. X
  515. X    if (numins == 0) {
  516. X        print("No instruments found.\n");
  517. X        return;
  518. X    }
  519. X
  520. X    if (!noheader) {
  521. X        fprint(outfile,";\n; Sorted list of instruments\n");
  522. X        fprint(outfile,   "; --------------------------\n;\n");
  523. X        if (numfiles == 1)
  524. X            fprint3(outfile, "; Taken from file ", files[0], "\n");
  525. X        else {
  526. X            fprint(outfile,"; Taken from these files:\n;\n");
  527. X            for (i = 0; i < numfiles && !CtrlC; i++) {
  528. X                fprint3(outfile, ";     ", files[i], "\n");
  529. X            }
  530. X        }
  531. X        fprint(outfile,";\n");
  532. X    }
  533. X    if (dirname)
  534. X        fprint(outfile,"failat 30\n");
  535. X    for (i = 0; i < numins && !CtrlC; i++) {
  536. X        for (j = (dirname != 0); j >= 0 && !CtrlC; j--) {
  537. X            if (dirname) {
  538. X                fprint3(outfile, "copy ", ins[i], " to ");
  539. X                fprint3(outfile, dirname, "\n", "");
  540. X            } else
  541. X                fprint3(outfile, INDENT, ins[i], "\n");
  542. X        }
  543. X    }
  544. X}
  545. SHAR_EOF
  546. echo "extracting sonixpeek.n"
  547. sed 's/^X//' << \SHAR_EOF > sonixpeek.n
  548. X.TH SONIXPEEK 1 "AMIGA Programmer's Manual" "Copyright Eddy Carroll 1989"
  549. X.SH NAME
  550. XSonixPeek - lists instruments in Aegis Sonix scores
  551. X.SH SYNOPSIS
  552. XSonixPeek {-h} {-i} {-n} {-ofile} {-xdirectory} file ...
  553. X.SH DESCRIPTION
  554. XSonixPeek is a utility designed to make it easier to move score files from
  555. Xthe Aegis Sonix music package from one disk to another. The problem arises
  556. Xbecause a single Sonix score can use many different instruments, and all of
  557. Xthese instruments must be moved along with the score file to the new disk.
  558. X
  559. XThe filename you give SonixPeek should be the name of a Sonix score file.
  560. XIf you don't specify any additional options, it just scans that file
  561. Xbuilding a list of all the instruments found, and then outputs this
  562. Xlist to the screen.
  563. X
  564. XIf you specify a directory instead of a file, then
  565. XSonixPeek scans all the score files in that directory, building a list
  566. Xof instruments in each file. When it's finished, it outputs this list,
  567. Xminus duplicates. This lets you see the minimum set of instruments you
  568. Xneed to have available to play all of those scores.
  569. X
  570. XYou can include more than one file and/or directory on the command line.
  571. XIn this case, all the files and directories included are scanned.
  572. X
  573. XSonixPeek has a number of options which can be used to alter its behaviour.
  574. XThese are as follows:
  575. X
  576. X.in +4
  577. X.ti -4
  578. X-h@ @ Normally, SonixPeek outputs a header at the start of the list of
  579. Xinstruments, showing which files the instruments come from. This option
  580. Xstops the header from being printed.
  581. X
  582. X.ti -4
  583. X-i@ @ This option makes SonixPeek prompt you for confirmation for each score
  584. Xfile it finds, before including its instruments in the instrument list.
  585. XThis is useful if you have a directory containing a large number
  586. Xof score files, and you want to find out the instruments in about half
  587. Xof them, since it saves you having to type each name out seperately.
  588. X
  589. X.ti -4
  590. X-n@ @ SonixPeek normally prints out a list of files scanned and instruments
  591. Xfound as it is building the main instrument list (unless only a single file
  592. Xwas specified on the command line). This option suppresses the list.
  593. X
  594. X.ti -4
  595. X-oF@ This option makes SonixPeek output the final list of instruments to the
  596. Xfile F, rather than standard output. This provides an alternative to
  597. Xredirecting standard output with >F. There is a small difference between the
  598. Xtwo however - the list of files mentioned in the discussion of -n is always
  599. Xsent to standard output, so using -o has no effect on it.
  600. X
  601. X.ti -4
  602. X-xD@ This option can be used to help simplify moving the instruments for
  603. Xa set of scores to another disk. When specified, SonixPeek outputs a script
  604. Xfile suitable for use with AmigaDOS's EXECUTE command. This script file
  605. Xcopies all the instruments for the files scanned to directory D. Before
  606. Xexecuting the script file, you should change your current directory to the
  607. Xdirectory where all the instrument files are stored.
  608. X
  609. X.in -4
  610. XYou can get a brief summary of the options available by invoking SonixPeek
  611. Xwith no parameters. CTRL-C can be used to abort SonixPeek at any time.
  612. X.SH CAVEATS
  613. XThere is one small problem with the automatic script file facility. Aegis
  614. XSonix supports two kinds of instruments, synthesised and sampled. Both types
  615. Xare stored in a .instr file, but sampled instruments also have an
  616. Xassociated .ss file. Since SonixPeek has no way of knowing whether a given
  617. Xinstrument is sampled or synthesised, it doesn't know whether there is a .ss
  618. Xfile that needs to be copied.
  619. X
  620. XThe solution is less than elegant but it works; SonixPeek assumes that
  621. XALL instruments have a .ss file, and sets the failat level
  622. Xfor the script file such that any copy commands which fail don't make the
  623. Xscript file abort. The only alternative to this would be to allow an
  624. Xinstrument directory to be specified as an option, and it would then be
  625. Xpossible to determine what type each instrument was. This seems too much
  626. Xlike hard work :-)
  627. X.SH AUTHOR
  628. XEddy Carroll
  629. X.br
  630. XThe Old Rectory,
  631. X.br
  632. XDelgany, Co. Wicklow,
  633. X.br
  634. XIreland.
  635. X
  636. XEMAIL: ecarroll@@cs.tcd.ie
  637. SHAR_EOF
  638. echo "extracting sonixpeek.uu"
  639. sed 's/^X//' << \SHAR_EOF > sonixpeek.uu
  640. X
  641. Xbegin 644 sonixpeek
  642. XM```#\P`````````"``````````$```,;```&XP```^D```,;2.=^_DOO`#0D'
  643. XM2"0`2?D`````+'@`!"E.`!`I3P`8D\E.KO[:)D`@#9"M``0&@````(`I0``$D
  644. XM0^P`)'``3J[]V"E``!QF```(<&1@``#H(&L`K-'(T<@B:``0T\G3R2`"<@`2$
  645. XM&2E)`"#0@5*`0F=2@`)`__Z?P%6`0G<(`"`"4X#4@1^R```@`%."4<C_]A^\V
  646. XM`"`@`%."'[$@`"``4<K_^")/G_P```"`)$\F2G0`831E$F?Z0>G__V$<82AF;
  647. XM_$(I__]@ZB!)80YA&F3\0BG__V$29OQGV"3(4D(,0@`@8R)P;F!0$!EG)@P`B
  648. XM`")G%@P``"!G"@P```EG!`P```H"/``>3G4`/``!`CP`^TYU+PLO`D?Y```$9
  649. XMC'(`(#P```7`8`(FP5'(__Q.N@&,<`!@!"`O``0O`"QX``0B;``<3J[^8B`?4
  650. XM+FP`&$S??WY.=0``3E7__$CG,`)*K`2,9CP@;0`,2AAF_%.(D>T`#"](``PBK
  651. XM+0`()"T`#"8O``PL;``<3J[_T'``<@`L>``$3J[^S@*````0`(&L!(Q,WT`,*
  652. XM3EU.=4Y5``!(YP`@(&T`#")(1>P8C!399OQ![!B,(DA*&6;\4XF3R"`)T<`B:
  653. XM;0`0)$D0VF;\0>P8C")(2AEF_%.)D\@@"='`(FT`%"1)$-IF_$AL&(PO+0`(_
  654. XM80#_5E!/3-\$`$Y=3G5.50``2.<P`DJL!(QG%"(L%W1![`!$)`AV`RQL`!Q.H
  655. XMKO_0(BP7?"0L%W"T@6<02H%G#"(L%WPL;``<3J[_W$JL%W1G#"(L%W0L;``<,
  656. XM3J[_W$JL&(1G#D'L&(1P`2QL&(A.KOYH2JP8B&<,(FP8B"QX``1.KOYB+RT`)
  657. XM"$ZZ_JY83TS?0`Q.74YU2&P!S$AL`0A(;`!(+RP7=&$`_P)/[P`02&P"=B\L?
  658. XM%W1A`/Z@4$].=4Y5__!(YR`"+&P`'$ZN_\HI0!=L0>P#$"(()#P```/N+&P`'
  659. XM'$ZN_^(I0!=T+&P`'$ZN_\0I0!=P*6P7<!=\<``I0!=X0^P#$G``+'@`!$ZN_
  660. XM_=@I0!B(2JP8B&8*2'@`8V$`_NY83UBM``P,K0````$`"&\``1PB;0`,(%$0V
  661. XM$`P``"UF``$,(DA2B1`1#```06T8#```6FX2(DA2B1`12(!(P`:`````(&`(>
  662. XM4H@0$$B`2,!R*`1!``AK``"PL+L0"&;R3OL0!@```'A@``"0````;V```#8`S
  663. XM``!N8```)@```&E@```4````:&````)P`2E`!)Q@``".<`$I0`208```A'`!&
  664. XM*4`$F&!Z(FT`#"!15(@O2``((B\`""0\```#[BQL`!Q.KO_B*4`7?$JL%WQFL
  665. XM4B)M``P@452(2&P#-B\(2&P#)"\L%W1A`/VB3^\`$$AX`!1A`/WZ6$]@*")M7
  666. XM``P@452(*4@$H&`:2&P#5"!M``PO$$AL`T0O+!=T80#];D_O`!!3K0`(6*T`3
  667. XM#&``_MP,K0````$`"&<.(FT`#"!1$!`,```_9@QA`/XN0J=A`/V@6$\,K0``Z
  668. XM``(`"&\&<`$I0`24#*T````!``AO``#B(FT`#"!1*TC_]"(M__1T_BQL`!Q.L
  669. XMKO^L*T#__$JM__QF(DAL`W(O+?_T2&P#8"\L%W1A`/SH3^\`$$AX`!1A`/U`S
  670. XM6$\B+?_\0>P7@"0(+&P`'$ZN_YI*K!>$;VYP`2E`!)0B+?_\+&P`'$ZN_X(KP
  671. XM0/_X<`!R`"QX``1.KO[.`H```!``@:P$C"(M__Q![!>`)`@L;``<3J[_E$J`?
  672. XM9QI*K`2,9A1*K!>$:L@O+?_T2&P7B&%,4$]@NB(M__@L;``<3J[_@BM`__A@%
  673. XM"D*G+RW_]&$N4$]3K0`(6*T`#&``_Q9A``6,(BW__"QL`!Q.KO^F0J=A`/R,A
  674. XM6$],WT`$3EU.=4Y5_X!(YS`B0JW_A"(M``@D/````^TL;``<3J[_XBE`%WA*3
  675. XMK!=X9AY(;`.2+RT`"$AL`X`O+!=T80#[XD_O`!!P_V```L`B+!=X0>W_]"0(0
  676. XM=@@L;``<3J[_UE&`9@H,K49/4DW_]&<2(BP7>"QL`!Q.KO_<</]@``*,(BP7'
  677. XM>$'M__0D"'8$+&P`'$ZN_]99@&8*#*U33553__1G$B(L%W@L;``<3J[_W'#_1
  678. XM8``"6$JL!)!G7DAL`ZPO+0`(2&P#GB\L%W1A`/M63^\`$"(L%VQ![?^0)`AV[
  679. XM,BQL`!Q.KO_6$"W_D`P``$%M$@P``%IN#$B`2,`&@````"!@"!`M_Y!(@$C`I
  680. XM#(````!Y9RIP_V```?1*K`249QY*K`289AA(;`.^2&P#NB\M``@O+!=P80#Z$
  681. XM[$_O`!!P`'(`+'@`!$ZN_LX"@```$`"!K`2,(BP7>$'M__0D"'8(+&P`'$ZNS
  682. XM_]91@&9T2JP$C&9N#*U)3E,Q__1G$"\M__@O+!=X80`!CE!/8+)(>``$+RP7L
  683. XM>&$``7Y03R`M__A2@`*`_____EF`+T``$"(L%WA![?_")`@F+P`0+&P`'$ZNO
  684. XM_]8@+?_X68!"-0C"2&W_PF$``<Y83W`!*T#_A&``_V!*K`249Q1*K`289@Y(U
  685. XM;`/`+RP7<&$`^=Q03TJM_X1G``#^2JT`#&<``*H@;0`,2AAF_%.(D>T`#")MJ
  686. XM``A*&6;\4XF3[0`((`DB"-"!5(`O0``0*T'_B$'L&(0@+P`0<@`L;!B(3J[^G
  687. XM="M`_XP@;0`,(FW_C!+89OQ*K?^(9S0@;?^,(BW_B!`P&/\,```Z9R(0,!C_M
  688. XM#```+V<8(DA*&6;\4XF3R"`)T<!#[`/")$D0VF;\(&W_C$H89OQ3B)'M_XP@G
  689. XM"")M_XS3P"!M``@2V&;\8#@@;0`(2AAF_%.(D>T`""`(4H`O0``00>P8A"`OY
  690. XM`!!R`"QL&(A.KOYT*T#_C"!M``@B;?^,$MAF_"`L!*CE@%*L!*A![!1,T<`@>
  691. XMK?^,(BP7>"QL`!Q.KO_<<`!,WT0,3EU.=4Y5_OA(YS`"<`$B+0`,4H$"@?__3
  692. XM__XK0/[\*T$`#'``<@`L>``$3J[^S@*````0`(&L!(Q*K0`,;TI*K?[\9T1*=
  693. XMK`2,9CXB+0`,#($```$`;P@@/````0!@`B`!+T``#"(M``A![?\`)`@F+P`,L
  694. XM+&P`'$ZN_]8K0/[\!*T```$```Q@FDS?0`Q.74YU3E7_\$CG`"(O+0`(80`!P
  695. XM?%A/*T#__%*`9P``@BML!*3_^%*L!*0B+?_XLJW__&\8(`'E@$'L!*S1P$/LJ
  696. XM!*C3P""14ZW_^&#>("W__.6`0>P$K-'`(FT`"$H99OQ3B9/M``@@"5*`+T``J
  697. XM#"](``A![!B$("\`#'(`+&P8B$ZN_G0@;P`(((`@+?_\Y8!![`2LT<`B;0`(P
  698. XM)%`4V6;\2JP$E&<>2JP$F&882&P#RB\M``A(;`/$+RP7<&$`]\I/[P`03-]$'
  699. XM`$Y=3G5.50``2.<@`"!M``A*$&=:(FT`#$H19U(2$`P!`$%M$@P!`%IN#$B!8
  700. XM2,$&@0```"!@"!`02(!(P"(`%!$,`@!!;1(,`@!:;@Q(@DC"!H(````@8`@0S
  701. XM$4B`2,`D`+*"9@I2K0`(4JT`#&">(&T`"!(0#`$`06T2#`$`6FX,2(%(P0:!W
  702. XM````(&`($!!(@$C`(@`@;0`,%!`,`@!!;1(,`@!:;@Q(@DC"!H(````@8`@0[
  703. XM$$B`2,`D`)*"(`%,WP`$3EU.=4Y5__A"K?_\(BW__+*L!*1L,B`!Y8!![`2LK
  704. XMT<`O$"\M``AA`/\:4$\K0/_X2H!N#DJ`9P8@+?_\8`YP_V`*4JW__&#$("W_E
  705. XM_$Y=3G5.5?_X2JP$I&822&P#S"\L%W1A`/9(4$]@``%:2JP$G&8``)A(;`/DK
  706. XM+RP7?&$`]BY03TAL!`0O+!=\80#V(%!/#*P````!!*AF&DAL!#@O+!1,2&P$:
  707. XM)"\L%WQA`/923^\`$&!(2&P$.B\L%WQA`/7N4$]"K?_\(BW__+*L!*AL+$JL`
  708. XM!(QF)B`!Y8!![!1,T<!(;`1@+Q!(;`18+RP7?&$`]@Y/[P`04JW__&#*2&P$D
  709. XM8B\L%WQA`/6F4$]*K`2@9PY(;`1F+RP7?&$`]9)03T*M__PB+?_\LJP$I&P`S
  710. XM`)A*K`2,9@``D$JL!*!6P$0`2(!(P"M`__A*K?_X:W!*K`2,9FI*K`2@9SP@V
  711. XM+?_\Y8!![`2LT<!(;`1X+Q!(;`1R+RP7?&$`]8I/[P`02&P$@$AL!'XO+`2@=
  712. XM+RP7?&$`]7)/[P`08"(@+?_\Y8!![`2LT<!(;`2(+Q!(;`2"+RP7?&$`]4Y/[
  713. XM[P`04ZW_^&"*4JW__&``_V!.74YU```#[`````(````!```!%`````X`````<
  714. XM```#\@```^H```$C````````````````````````````````````````````&
  715. XM````9&]S+FQI8G)A<GD`+G-S`"YI;G-T<@``````,````#1>0PH`"E-O;FEX%
  716. XM4&5E:R!);G-T<G5M96YT($QI<W1E<B!#;W!Y<FEG:'0@161D>2!#87)R;VQL?
  717. XM($%P<FEL(#$Y.#@*"E5S86=E.B!3;VYI>%!E96L@>RUH?2![+6E]('LM;GT@Y
  718. XM>RUO9FEL97T@>RUX9&ER96-T;W)Y?2!F:6QE("XN+@H*1FEL92!I<R!T:&4@!
  719. XM065G:7,@4V]N:7@@9FEL92!F;W(@=VAI8V@@=&AE(&EN<W1R=6UE;G1S(&%RT
  720. XM92!T;PH`8F4@;&ES=&5D+B!)9B!I="!I<R!A(&1I<F5C=&]R>2P@=&AE;B!A&
  721. XM;&P@=&AE(%-O;FEX(&9I;&5S(&EN"G1H870@9&ER96-T;W)Y(&%R92!C:&5C/
  722. XM:V5D+"!A;F0@82!S;W)T960@;&ES="!O9B!T:&4@:6YS=')U;65N=',*8V]N-
  723. XM=&%I;F5D(&EN(&%L;"!O9B!T:&5M(&ES('!R97!A<F5D+B!4:&4@9FQA9W,@S
  724. XM;W!E<F%T92!A<R!F;VQL;W=S.@H*`"`M:"`@4W5P<')E<W,@;W5T<'5T(&]FX
  725. XM(&AE861E<B!A="!S=&%R="!O9B!I;G-T<G5M96YT(&QI<W1I;F<*"B`M:2`@>
  726. XM07-K('5S97(@=VAE=&AE<B!O<B!N;W0@=&\@:6YC;'5D92!E86-H('-C;W)E[
  727. XM(&9O=6YD"@H@+6X@($1O;B=T(&QI<W0@:6YS=')U;65N=',@87,@=&AE>2!A>
  728. XM<F4@9F]U;F0*"@``("UO("!2961I<F5C="!S;W)T960@;W5T<'5T('1O(&YA)
  729. XM;65D(&9I;&4*"B`M>"`@1F]R;6%T(&]U='!U="!A<R!A;B!E>&5C=71E(&9IN
  730. XM;&4@=VAI8V@@=VEL;"!C;W!Y(&%L;"!T:&4*("`@("!I;G-T<G5M96YT<R!FM
  731. XM;W5N9"!T;R!T:&4@;F%M960@9&ER96-T;W)Y"@H``"H`:6YT=6ET:6]N+FQI8
  732. XM8G)A<GD`0V%N)W0@;W!E;B!F:6QE(```(&9O<B!O=71P=70N"@!5;FMN;W=N?
  733. XM(&]P=&EO;B``(&EG;F]R960N"@``0V%N)W0@;W!E;B!F:6QE(```(&9O<B!IH
  734. XM;G!U="X*``!#86XG="!O<&5N(&9I;&4@```@9F]R(&EN<'5T"@!);F-L=61EC
  735. XM(&9I;&4@`"`H0U(@/2!N;RD_(```.@H`````"@`O`"`@("````H`3F\@:6YS-
  736. XM=')U;65N=',@9F]U;F0N"@``.PH[(%-O<G1E9"!L:7-T(&]F(&EN<W1R=6UEO
  737. XM;G1S"@`[("TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM"CL*`#L@5&%K96X@)
  738. XM9G)O;2!F:6QE(```"@`[(%1A:V5N(&9R;VT@=&AE<V4@9FEL97,Z"CL*```[P
  739. XM("`@("````H`.PH``&9A:6QA="`S,`H``&-O<'D@`"!T;R````H````@("`@U
  740. XB```*```````#[`````(````!````0````#P````````#\B``-
  741. X``
  742. Xend
  743. Xsize 4444
  744. SHAR_EOF
  745. echo "extracting tiny.a"
  746. sed 's/^X//' << \SHAR_EOF > tiny.a
  747. X*:ts=8
  748. X****************************************************************************
  749. X*                                                                          *
  750. X* TINY.A                                  (C) Copyright Eddy Carroll 1989  *
  751. X* ~~~~~~                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  *
  752. X*                                                                          *
  753. X* This is a rewrite of the startup code provided with Lattice C V4.0.      *
  754. X* It is a "bare bones" version, which is substantially smaller, and also   *
  755. X* allows programs to be linked without needing to access lc.lib (unless    *
  756. X* of course they are using functions in lc.lib). Only CLI programs are     *
  757. X* supported, and no default i/o channels or other lattice-specific stuff   *
  758. X* are initialised. exit() doesn't automatically clean up any more, so      *
  759. X* don't use things like malloc() and fopen() unless you call free() and    *
  760. X* fclose() yourself. This replacement is designed for programs that go     *
  761. X* directly to AmigaDOS and Exec, rather than through the Unix-like Lattice *
  762. X* functions.                                                               *
  763. X*                                                                          *
  764. X* All in all, this version shaves around 1500 bytes off the size of a C    *
  765. X* program. No guarantees are supplied as regards its suitability for any   *
  766. X* particular use, other than it works for me.                              *
  767. X*                                                                          *
  768. X* Using it is very simple: Simply modify the command line for BLINK from   *
  769. X* BLINK FROM LIB:C.O+.... to BLINK FROM TINY.O+... and leave everything    *
  770. X* else the same.                                                           *
  771. X*                                                                          *
  772. X* Note that when assembling this, make sure to specify the -u switch on    *
  773. X* the Lattice assembler's command line. This adds a '_' to all symbols     *
  774. X* defined. If you are using a different assembler, you need to add a '_'   *
  775. X* manually yourself.                                                       *
  776. X*                                                                          *
  777. X****************************************************************************
  778. X
  779. X        INCLUDE "exec/types.i"
  780. X        INCLUDE "exec/alerts.i"
  781. X        INCLUDE "exec/nodes.i"
  782. X        INCLUDE "exec/lists.i"
  783. X        INCLUDE "exec/ports.i"
  784. X        INCLUDE "exec/libraries.i"
  785. X        INCLUDE "exec/tasks.i"
  786. X        INCLUDE "libraries/dos.i"
  787. X        INCLUDE "libraries/dosextens.i"
  788. X        INCLUDE "workbench/startup.i"
  789. X        INCLUDE "exec/funcdef.i"
  790. X        INCLUDE "exec/exec_lib.i"
  791. X        INCLUDE "libraries/dos_lib.i"
  792. X
  793. XMAXARGS        EQU 32    ; Maximum number of command line arguments from CLI
  794. XAbsExecBase EQU 4    ; Welcome to the only fixed point in the universe
  795. X
  796. X* A useful macro to let us call library routines
  797. Xcallsys macro
  798. X        CALLLIB _LVO\1
  799. X        endm
  800. X        
  801. X        xdef    XCEXIT            * exit(code) is standard way to exit C.
  802. X    xdef    exit                    *
  803. X
  804. X        xref    LinkerDB            * linker defined base value
  805. X        xref    _BSSBAS            * linker defined base of BSS
  806. X        xref    _BSSLEN            * linker defined length of BSS
  807. X
  808. X*       library references
  809. X
  810. X        csect   text,0,0,1,2        * xref's after this are 16-bit reloc
  811. X
  812. X        xref    main            * Name of C program to start with.
  813. X
  814. Xstart:
  815. X        movem.l d1-d6/a0-a6,-(a7)
  816. XREGSIZE EQU     (6+7)*4
  817. X        lea     REGSIZE(a7),A5         * Determine old stack pointer
  818. X        move.l  a0,a2                  * Save command pointer
  819. X        move.l  d0,d2                  * and command length
  820. X        lea     LinkerDB,a4            * Load base register
  821. X
  822. X        move.l  AbsExecBase.W,a6
  823. X        move.l  a6,SysBase(A4)
  824. X        move.l  a7,_StackPtr(A4)       * Save stack ptr
  825. X
  826. X    suba.l    a1,a1
  827. X    callsys    FindTask           * Find out our task ID
  828. X    move.l    d0,a3
  829. X
  830. X*=======================================================================
  831. X*====== CLI Startup Code ===============================================
  832. X*=======================================================================
  833. X*
  834. X* Entry: D2 = command length
  835. X*        A2 = Command pointer
  836. XfromCLI:
  837. X        move.l  a5,D0           * get top of stack
  838. X        sub.l   4(a5),D0        * compute bottom 
  839. X        add.l   #128,D0         * allow for parms overflow
  840. X        move.l  D0,_base(A4)    * save for stack checking
  841. X*-----------------------------------------------------------------------
  842. X*  Open the DOS library:
  843. X
  844. XopenDOS
  845. X    lea     DOSName(A4),A1
  846. X    moveq.l #0,D0
  847. X    callsys OpenLibrary
  848. X    move.l  D0,DOSBase(A4)
  849. X    bne    getcom
  850. XnoDOS:
  851. X    moveq.l #100,d0
  852. X    bra     exit2
  853. X
  854. X*------ find command name:
  855. Xgetcom:
  856. X    move.l  pr_CLI(a3),a0
  857. X        add.l   a0,a0           * bcpl pointer conversion
  858. X        add.l   a0,a0
  859. X        move.l  cli_CommandName(a0),a1
  860. X        add.l   a1,a1           * bcpl pointer conversion
  861. X        add.l   a1,a1
  862. X
  863. X*------ collect parameters:
  864. X        move.l  d2,d0                   * get command line length
  865. X        moveq.l #0,d1
  866. X        move.b  (a1)+,d1
  867. X        move.l  a1,_ProgramName(A4)
  868. X        add.l   d1,d0                   * add length of command name
  869. X        addq.l  #1,d0                   * allow for space after command 
  870. X
  871. X        clr.w   -(A7)                   * set null terminator for command line
  872. X        addq.l  #1,D0                   * force to even number of bytes
  873. X        andi.w  #$fffe,D0               * (round up)
  874. X        sub.l   D0,A7                   * make room on stack for command line
  875. X        subq.l  #2,D0
  876. X        clr.w   0(A7,D0)
  877. X
  878. X*------ copy command line onto stack
  879. X        move.l  d2,d0                   * get command line length
  880. X        subq.l  #1,d0
  881. X        add.l   d1,d2
  882. X
  883. Xcopy_line:
  884. X        move.b  0(A2,D0.W),0(A7,D2.W)   * copy command line to stack
  885. X        subq.l  #1,d2
  886. X        dbf     d0,copy_line
  887. X        move.b  #' ',0(a7,d2.w)         * add space between command and parms
  888. X        subq.l  #1,d2
  889. X
  890. Xcopy_cmd:
  891. X        move.b  0(a1,d2.w),0(a7,d2.w)    * copy command name to stack
  892. X        dbf     d2,copy_cmd
  893. X    move.l    a7,a1            * Get pointer to new command line
  894. X
  895. X    sub.l    #(MAXARGS*4),a7        * Reserve space for argv[]
  896. X    move.l    a7,a2            * Initialise base into array
  897. X    move.l    a2,a3            * Save base of argv
  898. X    moveq    #0,d2            * Initialise argc
  899. X
  900. X*
  901. X* From here on down, A1 is pointer into command line
  902. X*
  903. Xbuild_argv:
  904. X    bsr.s    getnext            * Read next character from line
  905. X    bcs.s    doquote            * If quote, handle
  906. X    beq.s    build_argv        * If white space, skip over it
  907. X
  908. X    lea    -1(a1),a0        * Get address of this parameter
  909. X    bsr.s    bumpargv        * Store it to argv[] array
  910. Xbuild_2:
  911. X    bsr.s    getnext            * Get next character
  912. X    bne.s    build_2            * If not white space, keep looking
  913. X    clr.b    -1(a1)            * Zero-terminate current argument
  914. X    bra.s    build_argv        * And go back to get next argument
  915. X
  916. Xdoquote:
  917. X    move.l    a1,a0            * Get pointer to this argument
  918. X    bsr.s    bumpargv        * Output it to argv[]
  919. Xquote_2:
  920. X    bsr.s    getnext            * Get next character
  921. X    bcc.s    quote_2            * If not quote, keep looking
  922. X    clr.b    -1(a1)            * Zero-terminate current argument
  923. Xquote_3:
  924. X    bsr.s    getnext            * Get next character
  925. X    bne.s    quote_3            * Skip until space reached
  926. X    beq.s    build_argv        * Go back and read next argument
  927. X
  928. Xbumpargv:
  929. X    move.l    a0,(a2)+        * Output ptr to current argument
  930. X    addq    #1,d2            * Increment argc
  931. X    cmpi    #MAXARGS,d2        * Used up all our arguments yet?
  932. X    bls.s    qrts            * If not, then return
  933. X    moveq    #110,d0            * Else set return code
  934. X    bra.s    exit2            * And exit
  935. X
  936. X*
  937. X* Reads next character from command line. If zero, never returns, but
  938. X* drops into call to main. Else, returns, with C=1 if character is quote,
  939. X* Z=1 if character is white space.
  940. X*
  941. Xgetnext:
  942. X    move.b    (a1)+,d0        * Get character from command line
  943. X    beq.s    get_2            * Exit if end of line
  944. X    cmp.b    #34,d0            * Check if quote
  945. X    beq.s    isquote            * 
  946. X    cmp.b    #32,d0            * Check if space
  947. X    beq.s    isspace            *
  948. X    cmp.b    #9,d0            * Or tab
  949. X    beq.s    isspace            *
  950. X    cmp.b    #10,d0            * Or end of line
  951. Xisspace:
  952. X    andi    #$1E,ccr        * Clear carry flag, retaining Z
  953. Xqrts    rts
  954. X
  955. Xisquote:
  956. X    ori    #1,ccr            * Set carry flag
  957. X    andi    #$FB,ccr        * Clear zero flag
  958. X    rts                * And return
  959. X
  960. Xget_2:
  961. X    move.l    a3,-(a7)        * Push argv onto stack
  962. X    move.l    d2,-(a7)        * Push argc onto stack
  963. X
  964. X        lea     _BSSBAS,a3          * get base of BSS
  965. X        moveq   #0,d1
  966. X        move.l  #_BSSLEN,d0         * get length of BSS in longwords
  967. X        bra.s   clr_lp              * and clear for length given
  968. Xclr_bss move.l  d1,(a3)+
  969. Xclr_lp  dbf     d0,clr_bss
  970. X
  971. Xdomain:
  972. X    jsr    main(PC)        * Call main(argc,argv)
  973. X        moveq.l #0,d0               * Set successful status
  974. X        bra.s   exit2
  975. X
  976. Xexit:
  977. X_exit:
  978. XXCEXIT:
  979. X        move.l  4(SP),d0        * Extract return code
  980. Xexit2:
  981. X        move.l  d0,-(a7)
  982. X        move.l  AbsExecBase.W,a6
  983. X        move.l  DOSBase(A4),a1
  984. X        callsys CloseLibrary            * Close Dos library
  985. X
  986. X*------ this rts sends us back to DOS:
  987. XexitToDOS:
  988. X        MOVE.L  (A7)+,D0
  989. X        movea.l _StackPtr(a4),SP        * Restore stack ptr
  990. X        movem.l (a7)+,d1-d6/a0-a6
  991. X        rts
  992. X
  993. X*-----------------------------------------------------------------------
  994. X* Global definitions
  995. X*
  996. X        csect   __MERGED,1,,2,2
  997. X*
  998. X        xdef    NULL,SysBase,LoadAddress,DOSBase
  999. X        xdef    _oserr,_OSERR,_ONBREAK
  1000. X        xdef    _ProgramName,_StackPtr,_base
  1001. X*
  1002. XNULL           dc.l    0
  1003. X_base          dc.l    0
  1004. X_oserr         equ     *
  1005. X_OSERR         dc.l    0
  1006. X_ONBREAK       dc.l    0
  1007. XSysBase        dc.l    0
  1008. XLoadAddress    dc.l    0
  1009. X_StackPtr      dc.l    0
  1010. XDOSBase        dc.l    0
  1011. X_ProgramName   dc.l    0
  1012. XDOSName        dc.b    'dos.library',0
  1013. X
  1014. X        END
  1015. SHAR_EOF
  1016. echo "End of archive 1 (of 1)"
  1017. # if you want to concatenate archives, remove anything after this line
  1018. exit
  1019.